#ifndef STATUSWIDGET_H
#define STATUSWIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QtWidgets>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDebug>
#include "mainwindow.h"
#include "topbuttons.h"
#include "pages.h"
// mavlink
#define MAVLINK_USE_MESSAGE_INFO
#include <common/mavlink.h>

class StatusWidget : public QWidget
{
    Q_OBJECT
public:
    static StatusWidget& getInstance(){
        if(NULL == instance){
            mutex.lock();
            if(NULL == instance){
                instance = new StatusWidget();
            }
            mutex.unlock();
        }
        return *instance;
    }

    static void release(){
        if(instance != NULL){
            mutex.lock();
            delete instance;
            instance = NULL;
            mutex.unlock();
        }
    }

    // 在界面显示后，更新部分控件：3D模型、MavLink消息等
    void updateWidgetsAfterSetPage();
    // 当界面改变时，释放部分控件：3D模型、MavLink消息等
    void releaseWidgetsWhenPageChanged();

    QVBoxLayout *vBoxLayoutPage;
    TopButtons *topButtons;
    QSpacerItem *spacerUnderTopButtons;

    QHBoxLayout *hBoxLayoutMavlinkAndModel;
    QScrollArea *scrollAreaMavlinkMessages;
    QWidget *scrollAreaContentMavlinkMessages;
    QVBoxLayout *vBoxLayoutMavlinkMessages;

    // mavlink消息列表相关
    void addMavlinkMessage(mavlink_message_t *msg);
    QWidget* findMavlinkMessage(quint8 componentId, quint32 messageId);
    quint32 checkedMavlinkMessageId;
    quint8 checkedMavlinkComponentId;
    QTimer *timerUpdateMavlinkMessageDetail;
    QReadWriteLock rwlockMavlinkMessageDetail;
    QTimer *timerUpdateMavlinkMessageFrequency;
    QPushButton *buttonToggleMavlinkMessageUpdate;
    bool enableMavlinkMessageUpdate;
    QVBoxLayout *vBoxLayoutMessageAndModel;
    QScrollArea *scrollAreaMessageDetail;
    QWidget *scrollAreaContentMessageDetail;
    QVBoxLayout *vBoxLayoutMessageDetail;

    // 显示3D模型相关的
    QWidget *modelViewWidget;// 用于叠加显示的控件
    QVBoxLayout *vBoxLayoutModelView;// 叠加的布局，包括3D模型和一个label
    void addModelViewWidget();
    void removeModelViewWidget();
    float camerax, cameray, cameraz;// 用于调整/获取当前观察视角
    QString stringLabelModelViewCameraPosition;
    QLabel *labelModelViewCameraPosition;

public slots:
    void updateMavlinkMessage(mavlink_message_t msg);

private:
    explicit StatusWidget(QWidget *parent = nullptr);
    StatusWidget(const StatusWidget&other);
    StatusWidget& operator=(const StatusWidget&other);

    static QMutex mutex;
    static StatusWidget *instance;

protected:
    virtual void resizeEvent(QResizeEvent *event)override;

private slots:
    void updateStringModelViewCameraPosition(void);
    void updateMavlinkMessageDetailLayout(void);
    void updateMavlinkMessageDetailData(void);
    void UpdateMavlinkMessageFrequency(void);
    void toggleMavlinkMessageUpdateState(void);

signals:
};

class MavlinkMessage:public QPushButton
{
    Q_OBJECT
public:
    MavlinkMessage(mavlink_message_t *msg, QWidget* parent = nullptr);
    void updateText();

    quint32 messageId;
    quint8 componentId;
    QString name;
    quint32 count;
    quint32 lastCount;
    QTime time;
    QTime lastTime;
    float frequency;
    QReadWriteLock lock;
    mavlink_message_t message;

public slots:

private slots:

signals:

};

class MavlinkMessageField:public QHBoxLayout
{
    Q_OBJECT
public:
    MavlinkMessageField(QString name, QString type, QWidget* parent = nullptr){
        labelName = new QLabel(name);
        labelValue = new QLabel("0");
        labelType = new QLabel(type);
        this->setSpacing(0);
        this->setMargin(0);
        this->addWidget(labelName);
        this->setStretchFactor(labelName, 1);
        this->addWidget(labelValue);
        this->setStretchFactor(labelValue, 1);
        this->addWidget(labelType);
        this->setStretchFactor(labelType, 1);
    }

    QSize sizeHint() const
    {
        QSize size;
        int h = 24;
        size.setHeight(h);
        size.setWidth( h * 10 * 3);
        return size;
    }

    ~MavlinkMessageField()
    {
        if(labelName != nullptr)
        {
            labelName->setParent(nullptr);
            labelName->deleteLater();
        }
        if(labelValue != nullptr)
        {
            labelValue->setParent(nullptr);
            labelValue->deleteLater();
        }
        if(labelType != nullptr)
        {
            labelType->setParent(nullptr);
            labelType->deleteLater();
        }
    }

    void updateValue(QString value)
    {
        labelValue->setText(value);
    }

    QLabel *labelName;
    QLabel *labelValue;
    QLabel *labelType;

public slots:

signals:

};

#endif // STATUSWIDGET_H
